package com.shenzw.mybatisdemo.config;

import cn.hutool.core.codec.Base64;
import cn.hutool.extra.spring.SpringUtil;
import com.shenzw.mybatisdemo.aop.ConvertPathToBase64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Objects;

/**
 * 拦截请求参数
 *
 * @author shenzw
 * @date 2023/12/8
 */
@Slf4j
@ControllerAdvice
public class AppRequestBodyAdvice implements RequestBodyAdvice {

    private static final String PROFILE_DEV = "dev";

    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        // 只在 dev环境中有效，实际中可以根据情况修改
        if (!PROFILE_DEV.equals(SpringUtil.getActiveProfile())) {
            return false;
        }
        Class<?> parameterType = methodParameter.getParameterType();
        return Arrays.stream(parameterType.getDeclaredFields()).anyMatch(field -> Objects.nonNull(field.getAnnotation(ConvertPathToBase64.class)));
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        return httpInputMessage;
    }

    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        for (Field field : o.getClass().getDeclaredFields()) {
            ConvertPathToBase64 annotation = field.getAnnotation(ConvertPathToBase64.class);
            if (annotation == null) {
                continue;
            }
            field.setAccessible(true);
            try {
                Object value = field.get(o);
                if (value instanceof String) {
                    field.set(o, Base64.encode((value.toString())));
                }
            } catch (IllegalAccessException e) {
                log.error("Image url parse error", e);
            }
        }
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
}
